<template>
  <div class="waterfall">
    <div class="waterfall-content" id="waterfall-content">
      <div v-for="(img,index) in waterfallList" :key="index" 
        :style="{top:img.top+'px',left:img.left+'px',width:waterfallImgWidth+'px',height:img.height}"
        class="waterfall-item">
        <img v-lazy="img.src">
      </div>
    </div>
  </div>
</template>

<script>
import { debounce } from '../../utils/functionOptimization';

export default {
  data() {
    return {
      imgArr: [
        require('../../assets/image/waterfall1.jpg'),
        require('../../assets/image/waterfall2.jpg'),
        require('../../assets/image/waterfall3.jpg'),
        require('../../assets/image/waterfall4.jpg'),
        require('../../assets/image/waterfall5.jpg'),
        require('../../assets/image/waterfall6.jpg'),
        require('../../assets/image/waterfall7.jpg'),
        require('../../assets/image/waterfall8.jpg'),
        require('../../assets/image/waterfall9.jpg'),
        require('../../assets/image/waterfall10.jpg'),
        require('../../assets/image/waterfall11.jpg'),
        require('../../assets/image/waterfall12.jpg')
      ],
      waterfallList: [],//存放计算好的数据
      waterfallImgWidth: 0,//每一列的宽度
      waterfallImgCol: 5,//多少列
      waterfallImgRight: 10,//右边距
      waterfallImgBottom: 10,//下边距
      waterfallDeviationHeight: [],//存放瀑布流各个列的高度
      imgList: [],
      isLoadFinish: false
    }
  },
  created(){
    window.addEventListener('scroll', this.onScroll, false);
    for (let i = 0; i < 48; i++ ){
      this.imgList.push(this.imgArr[i % this.imgArr.length]);
    }
  },
  mounted(){
    this.calculationWidth();
  },
  beforeDestroy(){
    window.removeEventListener('scroll', this.onScroll, false);
  },
  methods:{
    // 增加防抖
    onScroll: debounce(
      function() {
        // 可滚动容器的高度
        // let innerHeight = document.querySelector('.app').clientHeight;
        // 屏幕尺寸高度
        let outerHeight = document.documentElement.clientHeight;
        // 可滚动容器超出当前窗口显示范围的高度
        let scrollTop = document.documentElement.scrollTop;
        // scrollTop在页面为滚动时为0，开始滚动后，慢慢增加，滚动到页面底部时，出现innerHeight <= (outerHeight + scrollTop)的情况，严格来讲，是接近底部。
        // console.log('可滚动容器的高度:' + innerHeight, '屏幕尺寸高度:' + outerHeight, '可滚动容器超出当前窗口显示范围的高度:' + scrollTop)
        // 当滚动条高度+屏幕尺寸大于图片最小高度，并且上一次图片已加载完毕时，加载新的图片
        if (outerHeight + scrollTop >= Math.min.apply(null,this.waterfallDeviationHeight) && this.isLoadFinish) {
          // 加载更多操作
          for (let i = 0; i < 24; i++){
            this.imgList.push(this.imgArr[i % this.imgArr.length]);
          }
          this.calculationWidth();
        }
      },
      1000,
      false
    ),
    //计算每个图片的宽度
    calculationWidth(){
      this.isLoadFinish = false;
      let domWidth = document.getElementById("waterfall-content").offsetWidth;
        this.waterfallImgWidth = (domWidth-this.waterfallImgRight*this.waterfallImgCol)/this.waterfallImgCol;
        //初始化偏移高度数组
        this.waterfallDeviationHeight = new Array(this.waterfallImgCol);
        for (let i = 0; i < this.waterfallDeviationHeight.length; i++){
          this.waterfallDeviationHeight[i] = 0;
        }
        this.imgPreloading();
    },
    //图片预加载，由于这个例子是重复图片加载，正常业务没有重复图片url可以和下面的方法合并
    imgPreloading(){
      let imgLoadNum = 0;
      for (let i = 0; i < this.imgArr.length; i++){
        let aImg = new Image();
        aImg.src = this.imgArr[i];
        aImg.onload = ()=>{
          imgLoadNum++;
          if(imgLoadNum === this.imgArr.length){
            this.pushImgList();
          }
        };
      }
    },
    // 图片预加载完毕，把图片添加到列表里
    pushImgList(){
      for (let i = 0; i < this.imgList.length; i++){
        let aImg = new Image();
        aImg.src = this.imgList[i];
        // aImg.onload = ()=>{
        let imgData = {};
        imgData.height = this.waterfallImgWidth / aImg.width * aImg.height;
        imgData.src = aImg.src;
        this.waterfallList.push(imgData);
        this.rankImg(imgData);

        if(i === this.imgList.length - 1){
          this.isLoadFinish = true;
        }
        // }
      }
    },
    //瀑布流布局
    rankImg(imgData){
      let { waterfallImgWidth, waterfallImgRight, waterfallImgBottom, waterfallDeviationHeight } = this;
      let minIndex = this.filterMin();
      imgData.top = waterfallDeviationHeight[minIndex];
      imgData.left = minIndex*( waterfallImgRight + waterfallImgWidth );
      waterfallDeviationHeight[minIndex] += imgData.height + waterfallImgBottom;
    },
    // 找到最短的列并返回下标
    filterMin(){
      const min = Math.min.apply(null, this.waterfallDeviationHeight);
      return this.waterfallDeviationHeight.indexOf(min);
    }
  }
}
</script>

<style scoped>
.waterfall {
  padding: 80px;
}
.waterfall-content {
  position: relative;
  width: 100%;
  height: 100%;
}
.waterfall-item {
  position: absolute;
}
.waterfall-item img{
  width: 100%;
  height: 100%;
}
</style>